#ifndef _MAT_4X4_H_
#define _MAT_4X4_H_

#include "vec3.h"
#include "vec2.h"

namespace math
{

struct MATRIX44
{
    union {
        struct {
            float        _11, _12, _13, _14;
            float        _21, _22, _23, _24;
            float        _31, _32, _33, _34;
            float        _41, _42, _43, _44;

        };
        float m[4][4];
    };

	MATRIX44(	float m11, float m12, float m13, float m14,
					float m21, float m22, float m23, float m24,
					float m31, float m32, float m33, float m34,
					float m41, float m42, float m43, float m44 ):
					 _11(m11) , _12(m12),  _13(m13), _14(m14),
					 _21(m21), _22(m22),  _23(m23), _24(m24),
					 _31(m31), _32(m32),  _33(m33), _34(m34),
					 _41(m41), _42(m42),  _43(m43), _44(m44)
	{}
	MATRIX44()
	{

	}

} ;	
///////////////////////////////////////////////////////
///	\brief	Mat4x4 class that provides basic matrix 
///	 functionality. flexibility is preferred over speed.
///////////////////////////////////////////////////////
class Mat4x4 : public MATRIX44
{
public:	
	Mat4x4();
	Mat4x4(	const float* _m);
	Mat4x4(	float _fRoll, float _fPitch, float _fYaw);
	Mat4x4(	float _11, float _12, float _13, float _14,
                float _21, float _22, float _23, float _24,
                float _31, float _32, float _33, float _34,
                float _41, float _42, float _43, float _44 );

	void		Identity();

	// Scale / translate
	void		Scale(float _x, float _y, float _z);
	void		Translation(float _x, float _y, float _z);
	void		Translation(const Vec3& _vPos);

    // Transform
    math::Vec3  Transform(const math::Vec3& _Pos) const; 

	// Rotation axis
	void		RotateX(float _fDeg);
	void		RotateY(float _fDeg);
	void		RotateZ(float _fDeg);
	void		RotateAxis(float _fDeg, const Vec3& _vAxis);

	Vec3		GetDir() const;
	Vec3		GetRight() const;
	Vec3		GetUp() const;
	Vec3		GetPos() const;
	void		SetPos(const Vec3 NewPos);
	const float*	Get() const;

//    const D3DXMATRIXA16* GetD3DX() const  { return this; };

	Mat4x4		operator!()const;							// Inverse matrix
	Mat4x4		operator~()const;							// Transpose

	// Copy constructors
	Mat4x4		operator=(const Mat4x4		&_A);				// Copy

};
} // end namespace math

math::Mat4x4		operator*(const math::Mat4x4 &A, const math::Mat4x4 &B);	// Mat4x4 Multiply


#endif // _MAT_4X4_H_